/*
* INSANE - Interactive Structural Analysis Environment
*
* Copyright (C) 2003-2005
* Universidade Federal de Minas Gerais
* Escola de Engenharia
* Departamento de Engenharia de Estruturas
* 
* Author's email :    insane@dees.ufmg.br
* Author's website :  http://www.dees.ufmg.br/insane
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package br.ufmg.dees.insane.materialMedia.constitutiveModel;

import java.io.Serializable;
import java.util.HashMap;

import br.ufmg.dees.insane.analysisModel.AnalysisModel;
import br.ufmg.dees.insane.continuousPointModel.ContinuousPointModel;
import br.ufmg.dees.insane.materialMedia.material.BiLinearPlasticIsotropic;
import br.ufmg.dees.insane.materialMedia.material.ConcreteCarreira;
import br.ufmg.dees.insane.materialMedia.material.ConcreteEC2;
import br.ufmg.dees.insane.materialMedia.material.ConcreteIzzudin2002;
import br.ufmg.dees.insane.materialMedia.material.ConcreteNB1;
import br.ufmg.dees.insane.materialMedia.material.ConcreteSun1993;
import br.ufmg.dees.insane.materialMedia.material.LinearElasticIsotropic;
import br.ufmg.dees.insane.materialMedia.material.LinearElasticOrthotropic;
import br.ufmg.dees.insane.materialMedia.material.LinearPlasticIsotropic;
import br.ufmg.dees.insane.materialMedia.material.LinearPlasticIsotropic2;
import br.ufmg.dees.insane.materialMedia.material.Material;
import br.ufmg.dees.insane.materialMedia.material.VonMises;
import br.ufmg.dees.insane.util.IMatrix;
import br.ufmg.dees.insane.util.IPoint3d;
import br.ufmg.dees.insane.util.IVector;

/** A class representing OnePointConstModel
 * @author CENOURA!!!
 * @since 22/05/2005
 */
public class OnePointConstModel implements ConstitutiveModel, Serializable {

	private static final long serialVersionUID = 1L;
	
	/** The strain of this owner used in fisically nonlinear analysis.*/
    public final String STRAINS = "STRAINS";
    /** The coords of this owner used in geometric nonlinear analysis.*/
    public final String COORDS = "COORDS";
        
    /**Constructs this Constitutive Model.*/
    public OnePointConstModel()
	{
	}
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.materialMedia.constitutiveModel.ConstitutiveModel#getLabel()
     */
    public String getLabel() {
        return "OnePointConstModel";
    }
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.materialMedia.constitutiveModel.ConstitutiveModel#mountCt(br.ufmg.dees.insane.analysisModel.AnalysisModel, br.ufmg.dees.insane.materialMedia.material.Material, java.util.HashMap)
     */
    public IMatrix mountCt(ContinuousPointModel am, Material mat, HashMap cv) {
    	this.check(am,mat);
    	IMatrix pointCoords = new IMatrix(3,1);
        pointCoords.setElement(0,0,((IPoint3d)cv.get(this.COORDS)).x);
        pointCoords.setElement(1,0,((IPoint3d)cv.get(this.COORDS)).y);
        pointCoords.setElement(2,0,((IPoint3d)cv.get(this.COORDS)).z);
        IMatrix l = am.getInternalVariableOperator(null,null,null,pointCoords);
        IMatrix Ct = new IMatrix(l.getNumCol(),l.getNumCol());
        IMatrix aux = new IMatrix(l.getNumCol(),l.getNumRow());
        aux.mulTransposeLeft(l,am.getDualInternalVariableOperator(mat.getPt(am.expandTensor((IVector)cv.get(this.STRAINS)))));
        Ct.mul(aux,l);
        return Ct;
     }

    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.materialMedia.constitutiveModel.ConstitutiveModel#mountCs(br.ufmg.dees.insane.analysisModel.AnalysisModel, br.ufmg.dees.insane.materialMedia.material.Material, java.util.HashMap)
     */
    public IMatrix mountCs(ContinuousPointModel am, Material mat, HashMap cv) {
    	this.check(am,mat);
    	IMatrix pointCoords = new IMatrix(3,1);
        pointCoords.setElement(0,0,((IPoint3d)cv.get(this.COORDS)).x);
        pointCoords.setElement(1,0,((IPoint3d)cv.get(this.COORDS)).y);
        pointCoords.setElement(2,0,((IPoint3d)cv.get(this.COORDS)).z);
        IMatrix l = am.getInternalVariableOperator(null,null,null,pointCoords);
        IMatrix Ct = new IMatrix(l.getNumCol(),l.getNumCol());
        IMatrix aux = new IMatrix(l.getNumCol(),l.getNumRow());
        aux.mulTransposeLeft(l,am.getDualInternalVariableOperator(mat.getPs(am.expandTensor((IVector)cv.get(this.STRAINS)))));
        Ct.mul(aux,l);
        return Ct;
    }

    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.materialMedia.constitutiveModel.ConstitutiveModel#mountDualInternalVariableVector(br.ufmg.dees.insane.util.IVector, br.ufmg.dees.insane.analysisModel.AnalysisModel, br.ufmg.dees.insane.materialMedia.material.Material, java.util.HashMap)
     */
    public IVector mountDualInternalVariableVector(IVector e, ContinuousPointModel am, Material mat, HashMap cv) {
    	this.check(am,mat);
        IMatrix aux = am.getDualInternalVariableOperator(mat.getPs(am.expandTensor(e)));
        return aux.mul(e);
    }

    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.materialMedia.constitutiveModel.ConstitutiveModel#check(br.ufmg.dees.insane.analysisModel.AnalysisModel)
     */
    public void check(AnalysisModel am)throws AnalysisModelNotValid {
    }
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.materialMedia.constitutiveModel.ConstitutiveModel#check(br.ufmg.dees.insane.analysisModel.AnalysisModel)
     */
    public void check(ContinuousPointModel am)throws ContinuousPointModelNotValid {
        if (!(am instanceof ContinuousPointModel)) {
            throw new ContinuousPointModelNotValid(this.getLabel()+" and "+am.getLabel());
        }
    }
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.materialMedia.constitutiveModel.ConstitutiveModel#check(br.ufmg.dees.insane.materialMedia.material.Material)
     */
    public void check(Material mat)throws MaterialNotValid {
        if (!(mat instanceof LinearElasticIsotropic || 
                mat instanceof LinearElasticOrthotropic ||
                mat instanceof LinearPlasticIsotropic ||
                mat instanceof BiLinearPlasticIsotropic ||
                mat instanceof LinearPlasticIsotropic2 ||
                mat instanceof VonMises ||
                mat instanceof ConcreteIzzudin2002 ||
                mat instanceof ConcreteSun1993 ||
                mat instanceof ConcreteCarreira ||
                mat instanceof ConcreteEC2 ||
                mat instanceof ConcreteNB1)) {
                throw new MaterialNotValid(this.getLabel()+" and "+mat.getClass());
            }
        
    }

    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.materialMedia.constitutiveModel.ConstitutiveModel#mountC(br.ufmg.dees.insane.analysisModel.AnalysisModel, br.ufmg.dees.insane.materialMedia.material.Material, java.util.HashMap)
     */
    public IMatrix mountC(AnalysisModel am, Material mat, HashMap cv) {
    	return null;
    }
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.materialMedia.constitutiveModel.ConstitutiveModel#mountC(br.ufmg.dees.insane.analysisModel.AnalysisModel, br.ufmg.dees.insane.materialMedia.material.Material, java.util.HashMap)
     */
    public IMatrix mountC(ContinuousPointModel am, Material mat, HashMap cv) {
    	this.check(am,mat);
        IMatrix pointCoords = new IMatrix(3,1);
        pointCoords.setElement(0,0,((IPoint3d)cv.get(this.COORDS)).x);
        pointCoords.setElement(1,0,((IPoint3d)cv.get(this.COORDS)).y);
        pointCoords.setElement(2,0,((IPoint3d)cv.get(this.COORDS)).z);
        IMatrix l = am.getInternalVariableOperator(null,null,null,pointCoords);
        IMatrix C = new IMatrix(l.getNumCol(),l.getNumCol());
        IMatrix aux = new IMatrix(l.getNumCol(),l.getNumRow());
        aux.mulTransposeLeft(l,am.getDualInternalVariableOperator(mat.getPs(am.expandTensor((IVector)cv.get(this.STRAINS)))));
        C.mul(aux,l);
        return C;
    }
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.materialMedia.constitutiveModel.ConstitutiveModel#update(java.util.HashMap, java.util.HashMap)
     */
    public void update(HashMap<Object, Object> previous, HashMap<Object, Object> cv) {
        previous.put(this.STRAINS, cv.get(this.STRAINS));
    }
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.materialMedia.constitutiveModel.ConstitutiveModel#init(java.util.HashMap, java.util.HashMap, br.ufmg.dees.insane.analysisModel.AnalysisModel, br.ufmg.dees.insane.materialMedia.material.Material)
     */
    public void init(HashMap<Object, Object> previous, HashMap<Object, Object> cv, AnalysisModel am, Material mat) {
        previous.put(this.STRAINS, new IVector(am.getNumberOfInternalVariables()));
        cv.put(this.STRAINS, new IVector(am.getNumberOfInternalVariables()));
        cv.put(this.COORDS, new IPoint3d());
    }
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.materialMedia.constitutiveModel.ConstitutiveModel#init(java.util.HashMap, java.util.HashMap, br.ufmg.dees.insane.analysisModel.AnalysisModel, br.ufmg.dees.insane.materialMedia.material.Material)
     */
    public void init(HashMap<Object, Object> previous, HashMap<Object, Object> cv, ContinuousPointModel am, Material mat) {
        previous.put(this.STRAINS, new IVector(am.getNumberOfInternalVariables()));
        cv.put(this.STRAINS, new IVector(am.getNumberOfInternalVariables()));
        cv.put(this.COORDS, new IPoint3d());
    }
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.materialMedia.constitutiveModel.ConstitutiveModel#getNumberOfVariables()
     */
    public int getNumberOfVariables() {
        return 2;
    }
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.materialMedia.constitutiveModel.ConstitutiveModel#getNumberOfPreviousVariables()
     */
    public int getNumberOfPreviousVariables(){
        return 1;
    }
    
    private void check(ContinuousPointModel am, Material mat){
    	try {
			this.check(am);
			this.check(mat);
		} catch (ContinuousPointModelNotValid e) {
			e.printStackTrace();
            System.exit(0);
		}catch (MaterialNotValid e) {
			e.printStackTrace();
            System.exit(0);
		}
    }

	public IMatrix mountCt(AnalysisModel am, Material mat, HashMap cv) {
		// TODO Auto-generated method stub
		return null;
	}

	public IMatrix mountCs(AnalysisModel am, Material mat, HashMap cv) {
		// TODO Auto-generated method stub
		return null;
	}

	public IVector mountDualInternalVariableVector(IVector e, AnalysisModel am, Material mat, HashMap cv) {
		// TODO Auto-generated method stub
		return null;
	}
    
}
